package com.nehc.nettyserver.service.impl;

import com.nehc.nettyserver.common.model.Message;
import com.nehc.nettyserver.netty.ChannelManager;
import com.nehc.nettyserver.service.MessageService;
import com.nehc.nettyserver.service.NotificationService;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 通知服务实现类
 * 
 * @author NEHC
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class NotificationServiceImpl implements NotificationService {

    private final ChannelManager channelManager;
    private final MessageService messageService;
    private final ObjectMapper objectMapper = new ObjectMapper();
    
    // 用户未读通知缓存，Key: userId, Value: 未读通知列表
    private final ConcurrentHashMap<String, List<Message>> unreadNotificationsCache = new ConcurrentHashMap<>();
    
    @Override
    public int sendSystemNotification(String title, String content, Map<String, Object> params) {
        // 创建系统通知消息
        Message notification = createNotification(title, content, params, "notification");
        
        // 广播消息
        int recipientCount = broadcastNotification(notification);
        
        // 保存消息记录
        messageService.saveMessage(notification);
        
        return recipientCount;
    }

    @Override
    public boolean sendSystemNotificationToUser(String userId, String title, String content, Map<String, Object> params) {
        // 创建系统通知消息
        Message notification = createNotification(title, content, params, "notification");
        
        // 发送给指定用户
        boolean success = sendNotificationToUser(userId, notification);
        
        // 保存消息记录
        messageService.saveMessage(notification);
        
        return success;
    }

    @Override
    public int sendSystemWarning(String title, String content, Map<String, Object> params) {
        // 创建系统警告消息
        Message warning = createNotification(title, content, params, "warning");
        
        // 广播消息
        int recipientCount = broadcastNotification(warning);
        
        // 保存消息记录
        messageService.saveMessage(warning);
        
        return recipientCount;
    }

    @Override
    public boolean sendSystemWarningToUser(String userId, String title, String content, Map<String, Object> params) {
        // 创建系统警告消息
        Message warning = createNotification(title, content, params, "warning");
        
        // 发送给指定用户
        boolean success = sendNotificationToUser(userId, warning);
        
        // 保存消息记录
        messageService.saveMessage(warning);
        
        return success;
    }

    @Override
    public List<Message> getUnreadNotifications(String userId) {
        // 从缓存获取未读通知
        List<Message> unreadNotifications = unreadNotificationsCache.getOrDefault(userId, new ArrayList<>());
        
        // 如果缓存为空，则从存储服务获取
        if (unreadNotifications.isEmpty()) {
            try {
                // 这里应该根据实际存储实现来获取用户未读通知
                // TODO: 从存储服务加载未读通知
            } catch (Exception e) {
                log.error("Failed to load unread notifications for user: {}", userId, e);
            }
        }
        
        return unreadNotifications;
    }

    @Override
    public boolean markNotificationAsRead(String userId, String messageId) {
        List<Message> unreadNotifications = unreadNotificationsCache.getOrDefault(userId, new ArrayList<>());
        
        // 标记消息为已读
        boolean marked = false;
        List<Message> updatedList = unreadNotifications.stream()
                .filter(message -> {
                    if (message.getId().equals(messageId)) {
                        return false; // 移除匹配的消息
                    }
                    return true;
                })
                .collect(Collectors.toList());
        
        // 如果列表大小变化，说明找到并移除了消息
        if (updatedList.size() < unreadNotifications.size()) {
            unreadNotificationsCache.put(userId, updatedList);
            // 异步更新存储
            updateReadStatusInStorage(userId, messageId);
            marked = true;
        }
        
        return marked;
    }

    @Override
    public int markAllNotificationsAsRead(String userId) {
        List<Message> unreadNotifications = unreadNotificationsCache.getOrDefault(userId, new ArrayList<>());
        int count = unreadNotifications.size();
        
        if (count > 0) {
            // 清空未读消息
            unreadNotificationsCache.put(userId, new ArrayList<>());
            
            // 异步更新存储
            List<String> messageIds = unreadNotifications.stream()
                    .map(Message::getId)
                    .collect(Collectors.toList());
            updateAllReadStatusInStorage(userId, messageIds);
        }
        
        return count;
    }
    
    /**
     * 创建通知消息
     */
    private Message createNotification(String title, String content, Map<String, Object> params, String notificationType) {
        // 创建基础消息
        Message message = Message.createSystemMessage(content);
        
        // 添加通知特定属性
        message.addPayload("title", title);
        message.addPayload("notificationType", notificationType);
        
        // 添加附加参数
        if (params != null && !params.isEmpty()) {
            for (Map.Entry<String, Object> entry : params.entrySet()) {
                message.addPayload(entry.getKey(), entry.getValue());
            }
        }
        
        return message;
    }
    
    /**
     * 广播通知消息
     */
    private int broadcastNotification(Message notification) {
        try {
            String messageJson = objectMapper.writeValueAsString(notification);
            int count = channelManager.broadcast(messageJson);
            
            // 添加到所有在线用户的未读通知缓存
            channelManager.getAllClientIds().forEach(clientId -> {
                addToUnreadNotifications(clientId, notification);
            });
            
            return count;
        } catch (Exception e) {
            log.error("Failed to broadcast notification", e);
            return 0;
        }
    }
    
    /**
     * 发送通知消息给指定用户
     */
    private boolean sendNotificationToUser(String userId, Message notification) {
        try {
            String messageJson = objectMapper.writeValueAsString(notification);
            int count = channelManager.sendToUser(userId, messageJson);
            
            if (count > 0) {
                // 添加到用户未读通知缓存
                addToUnreadNotifications(userId, notification);
                return true;
            }
            
            return false;
        } catch (Exception e) {
            log.error("Failed to send notification to user: {}", userId, e);
            return false;
        }
    }
    
    /**
     * 添加消息到用户的未读通知缓存
     */
    private void addToUnreadNotifications(String userId, Message notification) {
        unreadNotificationsCache.compute(userId, (key, existingList) -> {
            if (existingList == null) {
                existingList = new ArrayList<>();
            }
            
            // 添加新通知到列表开头
            List<Message> newList = new ArrayList<>();
            newList.add(notification);
            newList.addAll(existingList);
            
            // 限制缓存大小，保留最新的100条
            if (newList.size() > 100) {
                return newList.subList(0, 100);
            }
            
            return newList;
        });
    }
    
    /**
     * 更新存储中的消息已读状态
     */
    private void updateReadStatusInStorage(String userId, String messageId) {
        // TODO: 实现存储服务的消息已读状态更新
        // 这里应该异步调用存储服务来更新消息状态
    }
    
    /**
     * 批量更新存储中的消息已读状态
     */
    private void updateAllReadStatusInStorage(String userId, List<String> messageIds) {
        // TODO: 实现存储服务的批量消息已读状态更新
        // 这里应该异步调用存储服务来批量更新消息状态
    }
} 